package com.file.system.plugin.task;

import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.file.system.entity.system.WebTask;
import com.file.system.service.impl.system.WebTaskServiceImpl;
import com.file.system.service.system.IWebTaskService;
import com.file.system.tools.Formater;
import com.file.system.tools.console.Read;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;


@Component
public class ScheduledConfig {

    @Autowired
    private IWebTaskService iWebTaskService;

    //线程池任务调度
    private ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    //正在
    private static ConcurrentHashMap<Long, ScheduledFuture> runTaskMap = new ConcurrentHashMap<Long, ScheduledFuture>();

    /**
     * 构造方法
     */
    public ScheduledConfig() {
        configureThreadPool();
        Read.console("task");
        startAll();
    }

    private void configureThreadPool() {
        this.threadPoolTaskScheduler.setPoolSize(10); // 线程池大小
        this.threadPoolTaskScheduler.setThreadNamePrefix("task-thread"); // 线程池名称
        this.threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true); // 设置等待任务在关机时完成
        this.threadPoolTaskScheduler.initialize(); // 初始化
    }


    /**
     * 根据定时任务id，启动定时任务
     */
    public boolean start(Long taskId) {
        try {
            WebTask webTask = iWebTaskService.getById(taskId);
            // 未找到任务
            if (webTask == null) {
                return false;
            }
            // 任务已在执行
            if (ScheduledConfig.runTaskMap.containsKey(taskId)) {
                return false;
            }

            // 获取并实例化Runnable任务类
            Class<?> clazz = Class.forName(webTask.getClassName());
            Runnable runnable = (Runnable) clazz.newInstance();

            // Cron表达式
            CronTrigger cron = new CronTrigger(webTask.getCron());
            // 加入正在运行集合
            ScheduledFuture<?> scheduledFuture = this.threadPoolTaskScheduler.schedule(runnable, cron);
            ScheduledConfig.runTaskMap.put(taskId, scheduledFuture);

            // 设置任务状态为启动
            webTask.setDictTaskStart("start");
            iWebTaskService.updateById(webTask);

            Read.console(Formater.getNow() + "        " + webTask.getName() + "启动");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 根据定时任务id，停止定时任务
     */
    public boolean stop(Long taskId) {
        // 根据任务id获取任务
        WebTask webTask = iWebTaskService.getById(taskId);
        if (webTask == null) {
            return false;
        }
        // 任务已在执行
        if (ScheduledConfig.runTaskMap.containsKey(taskId)) {
            // 获取任务定时任务
            ScheduledFuture<?> scheduledFuture = ScheduledConfig.runTaskMap.get(taskId);
            // 取消定时任务
            scheduledFuture.cancel(true);
            // 从任务定时任务map中移除任务
            ScheduledConfig.runTaskMap.remove(taskId);

            // 修改任务状态为停止
            webTask.setDictTaskStart("stop");
            // 更新任务
            iWebTaskService.updateById(webTask);
            // 打印任务停止信息
            Read.console(Formater.getNow() + "        " + webTask.getName() + "停止");
        }
        return true;
    }


    /**
     * 根据定时任务id，立刻执行一次
     */
    public boolean now(Long taskId) {
        try {
            // 根据任务ID获取任务
            WebTask webTask = iWebTaskService.getById(taskId);
            if (webTask == null) {
                return false;
            }
            // 获取并实例化Runnable任务类
            Class<?> clazz = Class.forName(webTask.getClassName());
            Runnable runnable = (Runnable) clazz.newInstance();
            // 创建新线程执行任务
            new Thread(runnable).start();
            // 打印执行信息
            Read.console(Formater.getNow() + "        " + webTask.getName() + "执行");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 启动所有定时任务
     */
    private void startAll() {
        // 获取WebTaskServiceImpl实例
        if (iWebTaskService == null) {
            iWebTaskService = SpringUtil.getBean(WebTaskServiceImpl.class);
        }
        // 查询所有未禁用任务
        List<WebTask> webTaskList = iWebTaskService.list(new QueryWrapper<WebTask>()
                .eq("is_del", 0)
                .eq("dict_on_off", "0")
        );
        // 循环启动任务
        for (WebTask webTask : webTaskList) {
            start(webTask.getId());
        }
    }


}
